import React, { useState, useRef, useEffect, useCallback } from 'react';
import './index.css';

// 队列类（复用原逻辑）
class Queue {
  constructor() {
    this.count = 0;
    this.lowestCount = 0;
    this.items = {};
  }
  enqueue(element) {
    this.items[this.count] = element;
    this.count += 1;
  }
  isEmpty() {
    return this.count - this.lowestCount === 0;
  }
  size() {
    return this.count - this.lowestCount;
  }
  dequeue() {
    if (this.isEmpty()) return undefined;
    const result = this.items[this.lowestCount];
    delete this.items[this.lowestCount];
    this.lowestCount += 1;
    return result;
  }
}

// MQTT 连接类（复用原逻辑）
class MQConnection {
  constructor(url) {
    this.socketUrl = url;
    this.options = { clientId: 'mqtt_' + Math.random().toString(16).substr(2, 8) };
    this.mqttClient = null;
    this.subscribeList = [];
  }
  initConnection() {
    if (this.mqttClient) return;
    this.mqttClient = window.mqtt.connect(this.socketUrl);
    this.mqttClient.on('connect', () => {
      console.log('MQTT 连接成功:', this.socketUrl);
      this.subscribeList.forEach(item => {
        this.mqttClient.subscribe(item.topic, () => {
          console.log('订阅成功:', item.topic);
        });
      });
    });
    this.mqttClient.on('message', (topic, message) => {
      const handler = this.subscribeList.find(item => item.topic === topic)?.messageHandler;
      if (handler) handler(message);
    });
    this.mqttClient.on('error', (error) => {
      console.error('MQTT 连接失败:', error);
    });
  }
  subscribe(topic, messageHandler) {
    this.subscribeList.push({ topic, messageHandler });
  }
  disconnection() {
    if (this.mqttClient) {
      this.mqttClient.end();
      this.mqttClient = null;
    }
  }
}

const Thing3DScene = () => {
  // 状态管理
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [followCar, setFollowCar] = useState(false);
  const [heatmapVisible, setHeatmapVisible] = useState(true);
  
  // DOM 引用
  const sceneRef = useRef(null); // 3D 场景容器
  const appRef = useRef(null); // THING.App 实例
  const mqttRef = useRef(null); // MQTT 实例
  const carRef = useRef(null); // 小车模型引用
  const manListRef = useRef([]); // 人物模型列表
  const heatmapRef = useRef(null); // 热力图引用
  
  // 常量定义
  const origin = [1, 0, 3]; // 原点坐标
  const urlLocaltest = 'ws://192.168.0.104:8083/mqtt'; // MQTT 服务器地址

  // 初始化 3D 场景
  useEffect(() => {
    if (!sceneRef.current) return;

      // 确认 ThingJS 已加载
    if (!window.THING) {
      console.error('ThingJS 未加载，请检查引入是否正确');
      return;
    }

    const initScene = () => {
      // 初始化 THING 应用
      appRef.current = new window.THING.App({
        container: sceneRef.current,
        // url: '/api/scene/4d34d0b7e442bbd025dc3d3e' // 场景资源地址
        // url: 'https://www.thingjs.com/static/models/scene/office.js' // 场景资源地址
        // url: 'https://www.thingjs.com/static/models/factory',  // 场景地址
        url: 'https://www.thingjs.com/static/models/scene/building.js', // 官方示例场景
      });

      const app = appRef.current;
  
      // 场景加载完成回调
      app.on('load', () => {
        console.log('3D 场景加载完成');
        
        // 初始化 MQTT 连接
        mqttRef.current = new MQConnection(urlLocaltest);
        mqttRef.current.subscribe('Location', handleLocationMessage);
        mqttRef.current.subscribe('wifiheatmap', handleHeatmapMessage);
        mqttRef.current.subscribe('Animation', handleAnimationMessage);
        mqttRef.current.subscribe('people', handlePeopleMessage);
        mqttRef.current.initConnection();
  
        // 获取小车模型
        carRef.current = app.query('car')[0];
        carRef.current.position = origin;
  
        // 创建人物模型
        const createMan = (index) => {
          return app.create({
            type: 'Thing',
            name: `man${index}`,
            url: '/api/models/986096f683494b94903465fa437a425a/0/gltf/',
            position: [0, 0, -0.5 - index * 0.5],
            scale: [0.4, 0.4, 0.4],
            complete: (man) => {
              playAnimation(man, 'Stand', true); // 默认播放站立动画
              man.visible = false;
            }
          });
        };
        manListRef.current = [createMan(0), createMan(1), createMan(2)];
  
        // 创建热力图
        heatmapRef.current = app.create({
          parent: app.query('房间')[0],
          localPosition: [0, 0.05, 0],
          type: 'Heatmap',
          name: 'wifiHeatmap',
          width: 37.647,
          height: 64.706,
          minValue: 0,
          maxValue: 100,
          radius: 1,
          alpha: true,
          colorMap: [
            { value: 30, color: [0, 0, 255] },
            { value: 60, color: [255, 255, 0] },
            { value: 90, color: [255, 0, 0] }
          ]
        });
        heatmapRef.current.rotateX(90);
        heatmapRef.current.visible = heatmapVisible;
      });
    }
    
    // 检查 ThingJS 是否加载完成
    const checkThingJSLoaded = () => {
      if (window.THING) {
        // 加载完成，初始化场景
        initScene();
      } else {
        // 未加载完成，100ms 后重试
        setTimeout(checkThingJSLoaded, 100);
      }
    };

    // 开始检测
    checkThingJSLoaded();

    // 清理函数（组件卸载时）
    return () => {
      if (mqttRef.current) mqttRef.current.disconnection();
      if (appRef.current) appRef.current.destroy(); // 销毁场景
    };
  }, []);

  // MQTT 消息处理函数
  const handleLocationMessage = useCallback((message) => {
    if (!carRef.current) return;
    const data = JSON.parse(message.toString().replace(/'/g, '"'));
    const location = data.data[0];
    const position = [
      origin[0] + location.x / 100,
      0,
      origin[2] - location.y / 100
    ];
    // 小车平滑移动
    carRef.current.movePath({
      path: [carRef.current.position, position],
      orientToPath: true,
      time: 300
    });
  }, []);

  const handleHeatmapMessage = useCallback((message) => {
    if (!heatmapRef.current) return;
    const data = JSON.parse(message.toString().replace(/'/g, '"'));
    
    // 修正：使用闭包变量保存状态，移除 static
    // 用一个对象包裹，避免每次调用重置
    if (!handleHeatmapMessage.state) {
      handleHeatmapMessage.state = {
        collectingData: false,
        dataArray: []
      };
    }
    const { collectingData, dataArray } = handleHeatmapMessage.state;

    if (data.data[0].flag === 0) {
      handleHeatmapMessage.state.collectingData = true;
    } else if (data.data[0].flag === 1) {
      handleHeatmapMessage.state.collectingData = false;
      heatmapRef.current.setData(dataArray);
      handleHeatmapMessage.state.dataArray = []; // 清空数据
    }

    if (collectingData) {
      const values = data.data[0];
      const rssi = Math.max(0, 120 + values.RSSI); // 信号强度转换
      dataArray.push([values.X - 18.82, 32.35 - values.Y, rssi]);
    }
  }, []);

  const handleAnimationMessage = useCallback((message) => {
    if (manListRef.current.length === 0) return;
    const data = JSON.parse(message.toString().replace(/'/g, '"'));
    const action = data.data[0];
    // 播放第一个人物的动画
    playAnimation(manListRef.current[0], action, action === 'Stand' || action === 'Walk');
  }, []);

  const handlePeopleMessage = useCallback((message) => {
    const data = JSON.parse(message.toString().replace(/'/g, '"'));
    const people = data.data || [];
    
    // 更新人物可见性和位置
    manListRef.current.forEach((man, index) => {
      if (index < people.length) {
        const person = people[index].data[0];
        const position = [
          origin[0] + person.x * 0.01,
          0,
          origin[2] - person.y * 0.01
        ];
        man.visible = true;
        man.movePath({ path: [position], time: 0 });
      } else {
        man.visible = false;
      }
    });
  }, []);

  // 动画控制函数
  const playAnimation = (model, name, loop) => {
    model.playAnimation({
      name,
      loopType: loop ? window.THING.LoopType.Repeat : window.THING.LoopType.No,
      complete: () => {
        if (!loop) playAnimation(model, 'Stand', true); // 非循环动画结束后恢复站立
      }
    });
  };

  // 相机控制函数
  const flyToCamera = (position, target) => {
    appRef.current.camera.flyTo({ position, target, time: 2000 });
  };

  // 全屏控制
  const toggleFullscreen = () => {
    if (!sceneRef.current) return;
    if (!document.fullscreenElement) {
      sceneRef.current.requestFullscreen();
      setIsFullscreen(true);
    } else {
      document.exitFullscreen();
      setIsFullscreen(false);
    }
  };

  // 小车跟随控制
  const toggleFollowCar = () => {
    if (!carRef.current || !appRef.current) return;
    setFollowCar(!followCar);
    if (!followCar) {
      // 开启跟随：每帧更新相机位置
      appRef.current.on('update', 'followCar', () => {
        appRef.current.camera.position = carRef.current.selfToWorld([0, 5, -10]);
        appRef.current.camera.target = carRef.current.position;
      });
    } else {
      // 关闭跟随：移除事件监听
      appRef.current.off('update', null, 'followCar');
    }
  };

  return (
    <div className="scene-container">
      {/* 3D 场景容器 */}
      <div ref={sceneRef} className="thing-scene" style={{ width: '400px', height: '400px' }} />

      {/* 控制按钮区 */}
      <div className="control-panel">
        <button onClick={() => flyToCamera([2, 7, 1.5], [2, 0, 1.4])}>相机俯视</button>
        <button onClick={() => flyToCamera([3.27, 2.73, 5.26], [3.26, 2.22, 4.28])}>第一摄像头</button>
        <button onClick={() => flyToCamera([6.3, 3, 0.84], [3.75, 0.21, 0.2])}>第二摄像头</button>
        <button onClick={() => {
          setHeatmapVisible(!heatmapVisible);
          heatmapRef.current.visible = !heatmapVisible;
        }}>
          热力图 {heatmapVisible ? '隐藏' : '显示'}
        </button>
        <button onClick={toggleFollowCar}>
          {followCar ? '取消跟随小车' : '视角跟随小车'}
        </button>
        <button onClick={toggleFullscreen}>
          {isFullscreen ? '退出全屏' : '进入全屏'}
        </button>
      </div>
    </div>
  );
};

export default Thing3DScene;